package com.example.demo.project.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;

public class NumberUtils {
	
	private NumberUtils() {
		throw new AssertionError(getClass() + "不需要实例化!");
	}
	
	public static BigDecimal notNull(BigDecimal num, BigDecimal candidate) {
		return Utils.notNull(num, candidate);
	}

	public static Double notNull(Double num) {
		return (null == num) ? 0d : num.doubleValue();
	}
	
	public static BigDecimal notNull(BigDecimal num) {
		return notNull(num, BigDecimal.ZERO);
	}

    public static Integer notNull(Integer num) {
        return Utils.notNull(num, Integer.valueOf(0));
    }
	
	public static BigDecimal add(BigDecimal... ns) {
		BigDecimal sum = BigDecimal.ZERO;
		for (BigDecimal n : ns) {
			if (null != n) sum = sum.add(n);
		}
		return sum;
	}
	public static Double add(Double... ns) {
		Double sum = 0D;
		for (Double n : ns) {
			if (null != n) sum += n;
		}
		return sum;
	}
	
	public static BigDecimal subtract(BigDecimal a, BigDecimal b) {
		if (null == a) a = BigDecimal.ZERO;
		if (null == b) b = BigDecimal.ZERO;
		return a.subtract(b);
	}

	public static BigDecimal subtract(Number a, Number b) {
		if (a == null) a = 0d;
		if (b == null) b = 0d;
		return BigDecimal.valueOf(a.doubleValue()).subtract(BigDecimal.valueOf(b.doubleValue()));
	}
	
	public static BigDecimal multiply(BigDecimal a, BigDecimal b) {
		if (null == a) a = BigDecimal.ZERO;
		if (null == b) b = BigDecimal.ZERO;
		return a.multiply(b);
	}
	public static BigDecimal multiply(BigDecimal a, BigDecimal b, BigDecimal... ns) {
		if (null == a) a = BigDecimal.ZERO;
		if (null == b) b = BigDecimal.ZERO;
		BigDecimal result = a.multiply(b);
		if(ns!=null && ns.length>0){
			for(int i=0;i<ns.length;i++){
				if(ns[i] == null ) ns[i] = BigDecimal.ZERO;
				result = result.multiply(ns[i]);
			}
		}
		return result;
	}
	
	public static BigDecimal divide(BigDecimal a, BigDecimal b, int scale) {
		if (a == null || b == null || 0 == a.doubleValue() || 0 == b.doubleValue()) {
			return BigDecimal.ZERO.setScale(scale);
		}
		return a.divide(b, scale, BigDecimal.ROUND_HALF_UP);
	}
	
	public static BigDecimal divide(BigDecimal a, BigDecimal b) {
		return divide(a, b, 6);
	}

	public static BigDecimal percent(BigDecimal a, BigDecimal b) {
		if (null == b || 0 == b.doubleValue()) return null;
		return NumberUtils.divide(NumberUtils.multiply(a, BigDecimal.valueOf(100d)), b);
	}

	public static BigDecimal percent(BigDecimal a, BigDecimal b, int scale) {
		if (null == b || 0 == b.doubleValue()) return null;
		if (null == a) a = BigDecimal.ZERO;
		return NumberUtils.divide(NumberUtils.multiply(a, BigDecimal.valueOf(100d)), b, scale);
	}

	public static String numberFormate(Object obj, String pattern){
		try {
			if(!StringUtil.isMeaningFul(pattern))
				pattern = "###,###,###,###,###,###,##0.00";
			DecimalFormat df = new DecimalFormat(pattern);
			return df.format(obj);
		} catch (Exception e) {
			return "0.00";
		}
	}
	
	/**
	 * 将BigDecimal表示的浮点数转为人民币大写。
	 * @param n
	 * @param scale
	 * @return
	 */
	public static String toRmbUpper(BigDecimal n, int scale) {
		String[] uppers = new String[] { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };
		String[] ius = {"", "拾", "佰", "仟"};
		String[] ius2 = {"元", "万", "亿", "兆"};
		String[] dus = {"角", "分", "厘"};
		String[] ns = n.setScale(scale, BigDecimal.ROUND_HALF_UP).toString().split("\\.");
		
		StringBuilder r = new StringBuilder();
		
		// 整数部分，按4位为一组分组处理。
		String[] gs = ns[0].split("(?<=^\\d+)(?=(\\d{4})+$)");
		for (int gi = 0; gi < gs.length; gi++) {
			// 组信息
			String g = gs[gs.length - gi - 1];
			
			// 用于保存分组处理的最终结果。
			StringBuilder ng = new StringBuilder();
			
			// 将小写的序号对应上大写数组的序号，获取对应的大写值。
			int lastIndex = 0; // 用于记录上次处理的结果来过滤连续的0
			for (int i = 0; i < g.length(); i++) {
				int index = Integer.parseInt(Character.toString(g.charAt(g.length() - 1 - i)));
				if (0 != index) {
					ng.append(ius[i]).append(uppers[index]);
				} else {
					if (0 != lastIndex) ng.append(uppers[index]);
				}
				lastIndex = index;
			}
			
			// 清除尾部的0。
			String seg = ng.reverse().toString().replaceAll(uppers[0] + "$", "");
			r.insert(0, seg + (seg.equals("") ? uppers[0] : ius2[gi]));
		}
		
		// 浮点数部分
		if (1 < ns.length && 0 < scale) {
			String fp = ns[1].replaceAll("0+$", "");
			int count = Math.min(fp.length(), scale);
			if (0 < count) {
				for (int j = 0; j < count; j++) {
					int index = Integer.parseInt(Character.toString(fp.charAt(j)));
					r.append(uppers[index]);
					if (0 != index) {
						r.append(dus[j]);
					}
				}
				return r.toString().replaceAll(uppers[0] + "+", uppers[0]);
			}
		}
		return r.toString().replaceAll(uppers[0] + "+", uppers[0]) + "整";
	}
	
	public static String toRmbUpper(BigDecimal n) {
		return toRmbUpper(n, 2);
	}
	
	/**星期转中文**/
	public static String weekDayToChinese(Integer weekDay){
		String[] uppers = new String[] {"日", "一", "二", "三", "四", "五", "六" };
		return uppers[weekDay-1];
	}
	/**10以内数字转中文**/
	public static String numToChinese(Integer num){
		String[] uppers = new String[] {"零", "一", "二", "三", "四", "五", "六","七","八","九","十" };
		return uppers[num];
	}
	public static BigDecimal min(BigDecimal...a){
		if( a == null || a.length == 0) return null;
		BigDecimal min = a[0];
		if(min == null) min = BigDecimal.ZERO;
		for(int i = 1 ; i < a.length ;i++){
			BigDecimal a1 = (a[i] == null ? BigDecimal.ZERO : a[i]);
			if(a1.compareTo(min) < 0 )
				min = a1;
		}
		return min;
	}
	public static BigDecimal max(BigDecimal...a){
		if( a == null || a.length == 0) return null;
		BigDecimal max = a[0];
		if(max == null) max = BigDecimal.ZERO;
		for(int i = 1 ; i < a.length ;i++){
			BigDecimal a1 = (a[i] == null ? BigDecimal.ZERO : a[i]);
			if(a1.compareTo(max) > 0 )
				max = a1;
		}
		return max;
	}
	
}
